# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
import pymysql
import redis
import datetime
import re
import os
import zipfile
import random
import ua
from pyvirtualdisplay import Display


# Chrome代理模板插件(https://github.com/RobinDev/Selenium-Chrome-HTTP-Private-Proxy)目录
CHROME_PROXY_HELPER_DIR = 'Chrome-proxy-helper'
# 存储自定义Chrome代理扩展文件的目录
CUSTOM_CHROME_PROXY_EXTENSIONS_DIR = 'chrome-proxy-extensions'


# 单列模式
# def Singleton(cls):
#     _instance = {}
#
#     def _singleton(*args, **kargs):
#         if cls not in _instance:
#             _instance[cls] = cls(*args, **kargs)
#         return _instance[cls]
#
#     return _singleton
#
#
# @Singleton
class Ctrip():
    _instance_lock = None

    def __init__(self):

        HOST = 'oyo-scrapy-database.mysql.rds.aliyuncs.com'
        PORT = 3306
        USER = 'scrapy'
        PASSWD = 'Podf&T$2'
        DB = 'spider'
        CHARSET = 'utf8mb4'

        self.conn = pymysql.connect(host=HOST, port=PORT, user=USER, passwd=PASSWD, db=DB, charset=CHARSET)
        self.cur = self.conn.cursor()

        RHOST = '10.200.20.200'
        RPORT = 6379
        RPASSWORD = 'zhangym930920'
        RDB = 1
        self.r = redis.Redis(host=RHOST, port=RPORT, password=RPASSWORD, db=RDB, charset='utf-8', decode_responses=True)
        RHOST2 = 'prod-bigdata-scrapy.redis.rds.aliyuncs.com'
        RPORT2 = 6379
        RPASSWORD2 = 'YAGZ1GvCOThSOSTp'
        RDB2 = 7
        self.r2 = redis.Redis(host=RHOST2, port=RPORT2, password=RPASSWORD2, db=RDB2, charset='utf-8',
                              decode_responses=True)
        # 代理云IP获取
        self.get_proxy()


        now_time = datetime.datetime.now()
        yesterday = now_time + datetime.timedelta(days=0)
        self.batch_no = yesterday.strftime('%Y%m%d')

    # 单列模式
    def __new__(cls, *args, **kwargs):  # 这三个参数是解释器自动添加的，这些参数实际上是给__init__方法用的。
        if Ctrip._instance_lock is None:  # 如果这个实例对象还是None
            Ctrip._instance_lock = object.__new__(cls)  # 调用父类的__new__方法来开辟内存
        return Ctrip._instance_lock

    def login(self, username, password, CRS_ID, batch_no):
        now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')


        # 使用Chrome代理扩展 get_chrome_proxy_extension
        chrome_options = Options()
        try:
            chrome_options = Options()
            a = self.get_chrome_proxy_extension(proxy=self.proxy)
            print(a)
            chrome_options.add_extension(a)

            useragent = ua.get_ua()
            print(useragent)
            chrome_options.add_argument('user-agent=' + useragent)
            # 设置代理
            # chrome_options.add_argument("--proxy-server=http://"+self.proxy)
            # chrome_options.add_argument('--headless')
            chrome_options.add_argument('--disable-gpu')
            chrome_options.add_argument('log-level=3')
            prefs = {
                'profile.default_content_setting_values': {
                    'images': 2,
                    # 'javascript': 2
                }
            }
            chrome_options.add_experimental_option('prefs', prefs)
        except Exception as err:
            print(err)


        # chrome_options.add_argument('user-agent="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"')
        # chrome_options.add_argument("--proxy-server=http://%s" % (str(ip).strip()))
        # 虚拟窗口====
        display = Display(visible=0, size=(900, 800))
        display.start()
        # ===========
        driver = webdriver.Chrome(options=chrome_options)
        # driver.maximize_window()
        driver.set_page_load_timeout(30)
        driver.set_script_timeout(30)
        url = 'http://ebooking.ctrip.com/ebkassembly/login.aspx'

        try:
            driver.get(url)
            # 获取首页内容
            index_con = driver.page_source
            # print(index_con)
            # 点击用户名输入框
            input_username = driver.find_element_by_id('userName')
            input_username.clear()  # 清除输入框
            time.sleep(0.1)
            input_username.click()
            time.sleep(0.1)
            # 输入账号
            for i in username:
                input_username.send_keys(i)
                time.sleep(0.1)

            time.sleep(0.1)
            input_password = driver.find_element_by_id('userPwd')
            input_password.clear()  # 清除输入框
            time.sleep(0.1)
            input_password.click()
            time.sleep(0.1)
            # 输入密码
            for i in password:
                input_password.send_keys(i)
                time.sleep(0.1)

            if 'div class="slidebar-item" style="margin: 0px 0px 10px;" id="identifyCodeForUser1"' in index_con:
                print('滑块存在')
                # 代理云IP获取
                self.get_proxy()
                self.r.lpush('hotel_users_ctrip', (username, password, CRS_ID, batch_no))
                driver.quit()
                display.stop()
                return

            else:
                time.sleep(0.1)
                subbmit = driver.find_element_by_id('accSubmit')
                subbmit.click()
                time.sleep(3)
            con = driver.page_source
            # ###############################################################################################
        except Exception as err:
            print(err)
            if 'Message: unexpected alert open: {Alert text : 有携程网的【紧急】订单，立即点击“确定”前往处理}' in str(err):
                print('订单弹窗')
                sql = "insert into ota_back_account_status (CRS_ID,Ctrip_Username,Ctrip_Status,Ctrip_Date,batch_no) values('%s','%s','%s','%s','%s')  on  DUPLICATE key update Ctrip_Status='%s',Ctrip_Date='%s',Ctrip_Username='%s'" % (
                    CRS_ID, username, 0, now, batch_no, 0, now, username)
                # print(sql)
                self.sql_commit(sql)

                sql = "update ota_back_account_info set verify_time='%s' where CRS_ID='%s'" % (now, CRS_ID)
                self.sql_commit(sql)
                driver.quit()
                display.stop()
                return
            else:
                # 代理云IP获取
                self.get_proxy()
                try:
                    os.remove(a)
                except Exception as err:
                    print(err)
                # # 强制删除文件夹
                # shutil.rmtree(CUSTOM_CHROME_PROXY_EXTENSIONS_DIR)
                # self.proxy = self.r.rpop('proxy_ctrip')
                # print(self.proxy)
                self.r.lpush('hotel_users_ctrip', (username, password, CRS_ID, batch_no))
                driver.quit()
                display.stop()
                return

        # print(con)

        if '用户名或密码错误' in con or 'Incorrect user name or password' in con:
            print('用户名或密码错误')
            # sql="update hotel_users set Ctrip_Status=%s where Ctrip_Username='%s'"%(1,username)
            sql = "insert into ota_back_account_status (CRS_ID,Ctrip_Username,Ctrip_Status,Ctrip_Date,batch_no) values('%s','%s','%s','%s','%s')  on  DUPLICATE key update Ctrip_Status='%s',Ctrip_Date='%s',Ctrip_Username='%s'" % (
            CRS_ID, username, 1, now, batch_no, 1, now, username)
            self.sql_commit(sql)

            sql = "update ota_back_account_info set verify_time='%s' where CRS_ID='%s'" % (now, CRS_ID)
            self.sql_commit(sql)
            driver.quit()
            display.stop()


        elif 'HotelName' in con:
            # elif '<a href="javascript:" id="accSubmit" class="ebk3-btn ebk3-btn-org ebk3-btn-huge  ek3-btn-cDefault ebk3-btn-cNotAllowed">登录中。。。</a>' in con:
            print('登录成功')
            # sql = "update hotel_users set Ctrip_Status=%s where Ctrip_Username='%s'" % (0, username)
            sql = "insert into ota_back_account_status (CRS_ID,Ctrip_Username,Ctrip_Status,Ctrip_Date,batch_no) values('%s','%s','%s','%s','%s')  on  DUPLICATE key update Ctrip_Status='%s',Ctrip_Date='%s',Ctrip_Username='%s'" % (
            CRS_ID, username, 0, now, batch_no, 0, now, username)
            # print(sql)
            self.sql_commit(sql)

            sql = "update ota_back_account_info set verify_time='%s' where CRS_ID='%s'" % (now, CRS_ID)
            self.sql_commit(sql)
            driver.quit()
            display.stop()

        elif '请关注合作协议更新' in con:
            print('请关注合作协议更新')
            # sql = "update hotel_users set Ctrip_Status=%s where Ctrip_Username='%s'" % (2, username)
            sql = "insert into ota_back_account_status (CRS_ID,Ctrip_Username,Ctrip_Status,Ctrip_Date,batch_no) values('%s','%s','%s','%s','%s')  on  DUPLICATE key update Ctrip_Status='%s',Ctrip_Date='%s',Ctrip_Username='%s'" % (
            CRS_ID, username, 2, now, batch_no, 2, now, username)
            self.sql_commit(sql)

            sql = "update ota_back_account_info set verify_time='%s' where CRS_ID='%s'" % (now, CRS_ID)
            self.sql_commit(sql)
            driver.quit()
            display.stop()

        else:
            print('检查滑块')
            # 代理云IP获取
            self.get_proxy()
            # # 强制删除文件夹
            # shutil.rmtree(CUSTOM_CHROME_PROXY_EXTENSIONS_DIR)
            try:
                os.remove(a)
            except Exception as err:
                print(err)
            # self.proxy = self.r.rpop('proxy_ctrip')
            # print(self.proxy)
            # input('============')
            self.r.lpush('hotel_users_ctrip', (username, password, CRS_ID, batch_no))
            driver.quit()
            display.stop()
            return

            # source = driver.find_element_by_xpath("//*[@id='nc_1_n1t']/span")  # 需要滑动的元素
            # input('=====')

    def sql_commit(self, sql):
        HOST = 'oyo-scrapy-database.mysql.rds.aliyuncs.com'
        PORT = 3306
        USER = 'scrapy'
        PASSWD = 'Podf&T$2'
        DB = 'spider'
        CHARSET = 'utf8mb4'
        try:
            self.cur.execute(sql)
            self.conn.commit()
        except:
            self.conn = pymysql.connect(host=HOST, port=PORT, user=USER, passwd=PASSWD, db=DB, charset=CHARSET)
            self.cur = self.conn.cursor()
            self.cur.execute(sql)
            self.conn.commit()

    # Chrome代理扩展
    def get_chrome_proxy_extension(self, proxy):
        """获取一个Chrome代理扩展,里面配置有指定的代理(带用户名密码认证)
        proxy - 指定的代理,格式: username:password@ip:port
        """
        proxy = str(proxy).replace('http://', '')
        m = re.compile('([^:]+):([^\@]+)\@([\d\.]+):(\d+)').search(proxy)
        if m:
            # 提取代理的各项参数
            username = m.groups()[0]
            password = m.groups()[1]
            ip = m.groups()[2]
            port = m.groups()[3]
            # 创建一个定制Chrome代理扩展(zip文件)
            if not os.path.exists(CUSTOM_CHROME_PROXY_EXTENSIONS_DIR):
                os.mkdir(CUSTOM_CHROME_PROXY_EXTENSIONS_DIR)
            extension_file_path = os.path.join(CUSTOM_CHROME_PROXY_EXTENSIONS_DIR,
                                               '{}.zip'.format(proxy.replace(':', '_')))
            if not os.path.exists(extension_file_path):
                # 扩展文件不存在，创建
                zf = zipfile.ZipFile(extension_file_path, mode='w')
                zf.write(os.path.join(CHROME_PROXY_HELPER_DIR, 'manifest.json'), 'manifest.json')
                # 替换模板中的代理参数
                background_content = open(os.path.join(CHROME_PROXY_HELPER_DIR, 'background.js')).read()
                background_content = background_content.replace('%proxy_host', ip)
                background_content = background_content.replace('%proxy_port', port)
                background_content = background_content.replace('%username', username)
                background_content = background_content.replace('%password', password)
                zf.writestr('background.js', background_content)
                zf.close()

            return extension_file_path
        else:
            raise Exception('Invalid proxy format. Should be username:password@ip:port')

    def get_proxy(self):
        # 代理云IP获取
        datas = self.r2.keys('proxy_ip_pool:ctrip*')
        proxys = []
        for d in datas:
            ds = str(d).split('|')
            dailiyun_proxy = ds[1] + ':' + ds[2] + ':' + ds[3] + ':' + ds[4]
            proxys.append(dailiyun_proxy)
        self.proxy = random.sample(proxys, 1)[0]
        print(self.proxy)

if __name__ == '__main__':
    RHOST = '10.200.20.200'
    RPORT = 6379
    RPASSWORD = 'zhangym930920'
    RDB = 1
    r = redis.Redis(host=RHOST, port=RPORT, password=RPASSWORD, db=RDB, charset='utf-8', decode_responses=True)

    begin = Ctrip()

    while True:
        datas = r.blpop('hotel_users_ctrip')[1]

        if datas == None:
            break
        else:

            data = eval(datas)

            username = data[0]
            password = data[1]
            CRS_ID = data[2]
            batch_no = data[3]
            # username = '245551b50'
            # password = 'hcjd8623888'
            # CRS_ID = 'CN_ABA001'
            # username = 'yydjjd'
            # password = 'uyeef115'
            print(username, password, CRS_ID, batch_no)
            begin.login(username, password, CRS_ID, batch_no)
